package main

import (
	"fmt"
	"gitee.com/hakwolf/taibak/internal/models"
	"gitee.com/hakwolf/taibak/internal/modules/app"
	"gitee.com/hakwolf/taibak/internal/modules/logger"
	"gitee.com/hakwolf/taibak/internal/service"
	"os"
	"os/signal"
	"syscall"

	//"github.com/iikira/BaiduPCS-Go/login/pcsconfig"
	//pcsutil "github.com/iikira/BaiduPCS-Go/mypcsutil"
	"github.com/urfave/cli"
	//"github.com/ying32/govcl/vcl"
	"gopkg.in/macaron.v1"
	//"os"
)

func init() {
	//pcsutil.ChWorkDir()
	//
	//err := pcsconfig.Config.Init()
	//switch err {
	//case nil:
	//case pcsconfig.ErrConfigFileNoPermission, pcsconfig.ErrConfigContentsParseError:
	//	fmt.Fprintf(os.Stderr, "FATAL ERROR: config file error: %s\n", err)
	//	os.Exit(1)
	//default:
	//	fmt.Printf("WARNING: config init error: %s\n", err)
	//}
}

var (
	AppVersion           = "1.6"
	BuildDate, GitCommit string
)

func main() {

	//cliApp := cli.NewApp()
	//cliApp.Name = "qjhcron"
	//cliApp.Usage = "qjhcron service"
	//cliApp.Version, _ = goutil.FormatAppVersion(AppVersion, GitCommit, BuildDate)
	////cliApp.Commands = getCommands()
	//runService()
	////cliApp.Flags = append(cliApp.Flags, []cli.Flag{}...)
	//cliApp.Run(os.Args)
	runService()

	//vcl.Application.SetTitle("pjtaiui")
	//vcl.Application.SetScaled(true)
	//vcl.Application.Initialize()
	//vcl.Application.SetMainFormOnTaskBar(true)
	//vcl.Application.CreateForm(&FMainForm)
	//
	//vcl.Application.Run()

}

// getCommands
func getCommands() []cli.Command {
	command := cli.Command{
		Name:   "service",
		Usage:  "run web server",
		Action: runService,
		Flags: []cli.Flag{
			cli.StringFlag{
				Name:  "host",
				Value: "0.0.0.0",
				Usage: "bind host",
			},
			//cli.IntFlag{
			//	Name:  "port,p",
			//	Value: DefaultPort,
			//	Usage: "bind port",
			//},
			cli.StringFlag{
				Name:  "env,e",
				Value: "prod",
				Usage: "runtime environment, dev|test|prod",
			},
		},
	}

	return []cli.Command{command}
}

func runService() { //ctx *cli.Context
	// 设置运行环境
	setEnvironment() //ctx
	// 初始化应用
	//app.InitEnv(AppVersion)
	// 初始化模块 DB、定时任务等
	logger.InitLogger()
	//var err error
	//AppDir, err = goutil.WorkDir()
	initModule()
	// 捕捉信号,配置热更新等
	catchSignal() //catchSignal()
	//m := macaron.Classic()
	//// 注册路由
	//routers.Register(m)
	//// 注册中间件.
	//routers.RegisterMiddleware(m)
	//m.Run(host, port)
	//vcl.Application.SetTitle("pjtaiui")
	//vcl.Application.SetScaled(true)
	//vcl.Application.Initialize()
	//vcl.Application.SetMainFormOnTaskBar(true)
	//vcl.Application.CreateForm(&MainForm)
	//
	//vcl.Application.Run()
}

func initModule() {
	//if !app.Installed {
	//	return
	//}

	//config, err := setting.Read(app.AppConfig)
	//if err != nil {
	//	.Fatal("读取应用配置失败", err)
	//}
	//app.Setting = config

	// 初始化DB
	models.Db = models.CreateSqliteDb()
	// 创建数据库表
	migration := new(models.Migration)
	err := migration.Install("")
	if err != nil {
		//return json.CommonFailure(fmt.Sprintf("创建数据库表失败-%s", err.Error()), err)
		fmt.Println("创建数据库表失败-%s")
	}

	//// 创建安装锁
	//err = app.CreateInstallLock()
	//if err != nil {
	//	//return json.CommonFailure("创建文件安装锁失败", err)
	//	fmt.Println("创建文件安装锁失败")
	//}
	//
	//// 更新版本号文件
	//app.UpdateVersionFile()
	//
	//app.Installed = true

	// 版本升级
	upgradeIfNeed()

	// 初始化定时任务
	service.ServiceTask.Initialize()
	//service.ServiceTask.Run()

}

func setEnvironment() { //ctx *cli.Context
	env := "prod"
	//if ctx.IsSet("env") {
	//	env = ctx.String("env")
	//}

	//env = "dev" //modfy by qjh en prod
	switch env {
	case "test":
		macaron.Env = macaron.TEST
	case "dev":
		macaron.Env = macaron.DEV
	default:
		macaron.Env = macaron.PROD
	}
}

// 捕捉信号
func catchSignal() {
	c := make(chan os.Signal)
	// todo 配置热更新, windows 不支持 syscall.SIGUSR1, syscall.SIGUSR2
	signal.Notify(c, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM)
	for {
		s := <-c
		logger.Info("收到信号 -- ", s)
		switch s {
		case syscall.SIGHUP:
			logger.Info("收到终端断开信号, 忽略")
		case syscall.SIGINT, syscall.SIGTERM:
			shutdown()
		}
	}
}

// 应用退出
func shutdown() {
	defer func() {
		logger.Info("已退出")
		os.Exit(0)
	}()

	if !app.Installed {
		return
	}
	logger.Info("应用准备退出")
	// 停止所有任务调度
	logger.Info("停止定时任务调度")
	service.ServiceTask.WaitAndExit()
}

// 判断应用是否需要升级, 当存在版本号文件且版本小于app.VersionId时升级
func upgradeIfNeed() {
	currentVersionId := app.GetCurrentVersionId()
	// 没有版本号文件
	if currentVersionId == 0 {
		return
	}
	if currentVersionId >= app.VersionId {
		return
	}

	migration := new(models.Migration)
	logger.Infof("版本升级开始, 当前版本号%d", currentVersionId)

	migration.Upgrade(currentVersionId)
	app.UpdateVersionFile()

	logger.Infof("已升级到最新版本%d", app.VersionId)
}
